#include "mat_logicboard.h"
#include "mat_animation_mgr.h"
#include "mat_animation.h"
#include "mat_game.h"
#include "mat_gamerule.h"
#include "mat_gemcollect.h"
#include "mat_sfx_manager.h"
#include "mat_scoring.h"
#include "mat_level_manager.h"

#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "num/rand.h"

using namespace script;

MATLogicBoard& MATLogicBoard::Instance()
{
	static MATLogicBoard inst;
	return inst;
}


MATLogicBoard::MATLogicBoard() : m_SelectedIndexX(-1),
								 m_SelectedIndexY(-1),
								 m_pPart2dSelectedGem(NULL)
						
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			m_Board[y][x] = NULL;
		}
	}
	
	Clear();	

	
}


void	MATLogicBoard::Clear()
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Board[y][x])
			{
				m_Board[y][x]->m_IsFinish = true;
				m_Board[y][x] = NULL;
			}
		}

	}

	m_SelectedIndexX = -1;
	m_SelectedIndexY = -1;
	m_PathFinding.Reset();

	if(m_pPart2dSelectedGem)
	{
		m_pPart2dSelectedGem->ToDie();
		m_pPart2dSelectedGem = NULL;
	}

	ClearTiles();
}

void	MATLogicBoard::SetContentAt(int y, int x, MATGem* BC)
{
	if(BC == NULL && m_Board[y][x]) 
		m_Board[y][x]->m_IsFinish = true;
	m_Board[y][x] = BC;
}

MATGem*	 MATLogicBoard::GetContentAt(int y, int x)
{
	return m_Board[y][x];
}

bool		MATLogicBoard::IsFull() const
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if( m_Board[y][x] == NULL  &&
				m_Tiles[y][x] != TILE_UNREACHABLE &&
				m_Tiles[y][x] != TILE_UNREACHABLE2 
				)
				return false;
			
			if( (m_Board[y][x] && m_Board[y][x]->m_Type == 0) &&
				m_Tiles[y][x] != TILE_UNREACHABLE &&
				m_Tiles[y][x] != TILE_UNREACHABLE2 

				)
				return false;
		}

	}
	return true;
}


bool		MATLogicBoard::IsAllBig() const
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if( m_Board[y][x] == NULL  &&
				m_Tiles[y][x] != TILE_UNREACHABLE &&
				m_Tiles[y][x] != TILE_UNREACHABLE2 
				)
				return false;

			if(  ( m_Board[y][x] && 
				(m_Board[y][x]->m_IsSmall || m_Board[y][x]->m_Type == 0 )
				)  
				&&
				m_Tiles[y][x] != TILE_UNREACHABLE &&
				m_Tiles[y][x] != TILE_UNREACHABLE2
				)
				return false;
		}

	}
	return true;
}

void	MATLogicBoard::Tick(float dt)
{
	input::Mouse::BUTTON_STATE* pState =
	input::Mouse::Instance().GetButtonState(input::Mouse::BUTTON_LEFT);
	if(pState->IsButtonPressed())
		m_FirstMouseDownPos = input::Mouse::Instance().GetImmediatePos(); 
}

MATGem*		MATLogicBoard::MouseButtonDown(const math::Vec2& Pos, int Y, int X)
{
	if( (m_SelectedIndexY != -1 && m_SelectedIndexX != -1) 		
		)
		m_PathFinding.DoPathFinding(m_SelectedIndexY, m_SelectedIndexX, Y, X);

	if(m_Board[Y][X] == NULL)
		return NULL;

	if( (m_FirstMouseDownPos - Pos).Magnitude() > 0.025f)
		return m_Board[Y][X];
	
	if(!MATLevelManager::Instance().CanMove())
		return m_Board[Y][X];

	if( m_Board[Y][X]->m_Type == 0 ||  m_Board[Y][X]->m_IsSmall )
		return m_Board[Y][X];

	if( m_Tiles[Y][X] == TILE_UNMOVEABLEGEM || m_Tiles[Y][X] == TILE_UNMOVEABLEGEM2)
		return m_Board[Y][X];
	
    if( Y == m_SelectedIndexY && X == m_SelectedIndexX)
		return m_Board[Y][X];

	//if( m_SelectedIndexY != -1 && m_SelectedIndexX != -1)
	//	return m_Board[Y][X];

	if(IsMatchedXY(Y,X))
		return m_Board[Y][X];

	MATAnimation* pAni = MATAnimationManager::Instance().GetActiveAnimAt(Y,X);
	
	if(pAni && pAni->GetType() == MATAnimation::ANI_TYPE_MOVING)
		return m_Board[Y][X];

	if(IsAllBig())
		return m_Board[Y][X];

	if(m_pPart2dSelectedGem)
		m_pPart2dSelectedGem->ToDie();
	
	m_pPart2dSelectedGem = MATSFXManager::Instance().Spawn(MATSfx::SFX_SELECTED, MATGame::GetBoardPos(Y,X),1.0f,0,false,MATSounds::SFX_GEM_SELECTED);
	if(m_SelectedIndexY == -1 || m_SelectedIndexY == -1){}
	else if(m_Board[m_SelectedIndexY][m_SelectedIndexX] && m_Board[m_SelectedIndexY][m_SelectedIndexX]->m_IsGlow)
		m_Board[m_SelectedIndexY][m_SelectedIndexX]->m_IsGlow = false;

	m_SelectedIndexY = Y;
	m_SelectedIndexX = X;
	m_Board[Y][X]->m_IsGlow = true;
	

	return m_Board[Y][X];
	
}

void		MATLogicBoard::MouseButtonReleased(const math::Vec2& Pos, int Y, int X, bool& ToShowNotValidMove)
{
	if(MATLevelManager::Instance().IsPlaying() == false)
		return;

	if(MATAnimationManager::Instance().IsActiveAnimation(MATAnimation::ANI_TYPE_MOVING))
		return;

	if(MATAnimationManager::Instance().IsActiveAnimation(MATAnimation::ANI_TYPE_SMALLTOBIG))
		return;

	ToShowNotValidMove = false;
	if(m_SelectedIndexX < 0 || m_SelectedIndexY < 0)
	{
		m_SelectedIndexY = -1;
		m_SelectedIndexX = -1;
		return;
	}

	if(!m_Board[Y][X] || m_Board[Y][X]->m_IsSmall )
	{
		m_PathFinding.DoPathFinding(m_SelectedIndexY, m_SelectedIndexX, Y, X);

		if(m_PathFinding.IsFound())
		{
			m_LastMoveX = m_SelectedIndexX;
			m_LastMoveY = m_SelectedIndexY;
			m_LastMoveToX = X;
			m_LastMoveToY = Y;

			// can move
			MATAnimation* pAni = MATAnimationManager::Instance().AddAnimation(
														Y,
														X,
														m_Board[m_SelectedIndexY][m_SelectedIndexX], 
														MATAnimation::ANI_TYPE_MOVING
															);
			if(!pAni)
				return;

			m_Board[m_SelectedIndexY][m_SelectedIndexX]->m_IsGlow = false;

			((MATAniMoving*)pAni)->ClearPositions();		
			pAni->SetCallBack(this);
			const std::vector<MATPathFinding::Tile*> Tiles = m_PathFinding.GetPath();
			math::Vec2 Pos;
			for(int i = 0; i < (int)Tiles.size(); i++)
			{
				MATPathFinding::Tile* pTile = Tiles[i];
				Pos = MATGame::GetBoardPos(pTile->m_Y,pTile->m_X);
				((MATAniMoving*)pAni)->AddMovePosition(Pos);

			}

			//Swaping Animation
			if( m_Board[Y][X] && m_Board[Y][X]->m_Type > 0)
			{
				pAni = MATAnimationManager::Instance().AddAnimation(
														m_SelectedIndexY,
														m_SelectedIndexX,
														m_Board[Y][X], 
														MATAnimation::ANI_TYPE_MOVING
															);
				((MATAniMoving*)pAni)->ClearPositions();
				for(int i = (int)Tiles.size() - 1; i >=0 ; i--)
				{
					MATPathFinding::Tile* pTile = Tiles[i];
					Pos = MATGame::GetBoardPos(pTile->m_Y,pTile->m_X);
					((MATAniMoving*)pAni)->AddMovePosition(Pos);
				}
			}

			
			MATGem* TempBC = m_Board[Y][X];
			m_Board[Y][X] = m_Board[m_SelectedIndexY][m_SelectedIndexX];
			m_Board[m_SelectedIndexY][m_SelectedIndexX] = TempBC;

			MATSFXManager::Instance().Spawn(MATSfx::SFX_MOVETOTARGET, 
											MATGame::GetBoardPos( Y , X),
											1.0f,0,false,MATSounds::SFX_GEM_MOVE_START);

			//MATSFXManager::Instance().Spawn(MATSfx::SFX_MOVETOTARGET, 
			//								MATGame::GetBoardPos( m_SelectedIndexY , m_SelectedIndexY),
			//								1.0f);
			
					
			// predetermined
			CheckMatchXPlus();
			CheckMatchYPlus();
			CheckMatchXPlusYPlus();
			CheckMatchXPlusYMinus();
			m_PathFinding.Reset();
		}
		else
		{
			ToShowNotValidMove = true;
			return;
		}


	}
	else if ( (m_FirstMouseDownPos - Pos).Magnitude() < 0.025f)
	{
		// we are clicking to select it
		return;
	}
	
	if(m_pPart2dSelectedGem)
	{
		m_pPart2dSelectedGem->ToDie();
		m_pPart2dSelectedGem = NULL;
	}

	m_SelectedIndexY = -1;
	m_SelectedIndexX = -1;

}


bool		MATLogicBoard::CheckMatch5()
{
	m_SameXs.clear();
	m_SameYs.clear();

	CheckMatchXPlus();
	CheckMatchYPlus();
	CheckMatchXPlusYPlus();
	CheckMatchXPlusYMinus();

	bool ReturnVal = (m_SameXs.size() > 0);

	ClearMatch();
	if(ReturnVal)
	{
		//m_Score.Add(123);
	}
	else
	{
		MATScoring::Instance().ResetFromCombo();
	}

	return ReturnVal;
}



void		MATLogicBoard::CheckMatchXPlus()
{
	std::vector<int> XList;
	std::vector<int> YList;


	for(int y = 0; y < MATGameRule::Instance().GetBoardCountY(); y++  )
	{		
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX() - 1; x++)
		{
			if(	m_Board[y][x] && m_Board[y][x+1] &&
				m_Board[y][x]->m_Type != 0 &&  m_Board[y][x+1]->m_Type != 0 &&
				m_Board[y][x]->m_IsSmall == false && m_Board[y][x+1]->m_IsSmall == false &&
				m_Board[y][x]->m_Type == m_Board[y][x+1]->m_Type)

			{	
				if(XList.size() == 0)
				{
					XList.push_back(x);
					YList.push_back(y);
				}

				XList.push_back(x+1);
				YList.push_back(y);
			}			
			else
			{
				if(XList.size() >= 5)
				{
					AddToSameList(YList, XList);					
				}
				XList.clear();
				YList.clear();
			}
		}

		if(XList.size() >= 5)
		{
			AddToSameList(YList, XList);			
		}
		XList.clear();
		YList.clear();

		
	}
}
	
void		MATLogicBoard::CheckMatchYPlus()
{
	std::vector<int> XList;
	std::vector<int> YList;


	for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++  )
	{		
		for(int y = 0; y < MATGameRule::Instance().GetBoardCountY() - 1; y++)
		{
			if(	m_Board[y][x] && m_Board[y+1][x] &&
				m_Board[y][x]->m_Type != 0 &&  m_Board[y+1][x]->m_Type &&
				m_Board[y][x]->m_IsSmall == false && m_Board[y+1][x]->m_IsSmall == false &&
				m_Board[y][x]->m_Type == m_Board[y+1][x]->m_Type)

			{	
				if(XList.size() == 0)
				{
					XList.push_back(x);
					YList.push_back(y);
				}

				XList.push_back(x);
				YList.push_back(y+1);
			}			
			else
			{
				if(XList.size() >= 5)
				{
					AddToSameList(YList, XList);					
				}
				XList.clear();
				YList.clear();
			}
		}

		if(XList.size() >= 5)
		{
			AddToSameList(YList, XList);			
		}
		XList.clear();
		YList.clear();

		
	}
}

void		MATLogicBoard::CheckMatchXPlusYPlus()
{
	for(int y = 0; y < MATGameRule::Instance().GetBoardCountY() - 4; y++  )
	{		
		CheckMatchXPlusYPlusLine(y,0);
	}

	for(int x = 1; x < MATGameRule::Instance().GetBoardCountX() - 4; x++  )
	{		
		CheckMatchXPlusYPlusLine(0,x);
	}
}

	
void		MATLogicBoard::CheckMatchXPlusYMinus()
{
	for(int x = 1; x < MATGameRule::Instance().GetBoardCountX() - 4; x++  )
	{		
		CheckMatchXPlusYMinusLine(MATGameRule::Instance().GetBoardCountY() - 1,x);
	}
	
	for(int y = 4; y < MATGameRule::Instance().GetBoardCountY(); y++  )
	{		
		CheckMatchXPlusYMinusLine(y,0);
	}

	
}

void		MATLogicBoard::CheckMatchXPlusYPlusLine(int StartY, int StartX)
{
	std::vector<int> XList;
	std::vector<int> YList;

	int x = StartX;
	int y = StartY;

	while(x < MATGameRule::Instance().GetBoardCountX() - 1 && y < MATGameRule::Instance().GetBoardCountY() - 1)
	{
		if(	m_Board[y][x] && m_Board[y+1][x+1] &&
			m_Board[y][x]->m_Type != 0 &&  m_Board[y+1][x+1]->m_Type != 0 && 
			m_Board[y][x]->m_IsSmall  == false && m_Board[y+1][x+1]->m_IsSmall  == false &&
			m_Board[y][x]->m_Type == m_Board[y+1][x+1]->m_Type)

		{	
			if(XList.size() == 0)
			{
				XList.push_back(x);
				YList.push_back(y);
			}

			XList.push_back(x+1);
			YList.push_back(y+1);
		}	
		else
		{
			if(XList.size() >= 5)
			{

				AddToSameList(YList, XList);					
			}
			YList.clear();
			XList.clear();
		}

		x++;
		y++;
	}
	
	if(XList.size() >= 5)
	{

		AddToSameList(YList, XList);					
	}
	
}
	
void		MATLogicBoard::CheckMatchXPlusYMinusLine(int StartY, int StartX)
{
	std::vector<int> XList;
	std::vector<int> YList;

	int x = StartX;
	int y = StartY;

	while(x < MATGameRule::Instance().GetBoardCountX() - 1 && y > 0)
	{
		if(	m_Board[y][x] && m_Board[y-1][x+1] &&
			m_Board[y][x]->m_Type != 0 && m_Board[y-1][x+1]->m_Type != 0 &&
			m_Board[y][x]->m_IsSmall == false && m_Board[y-1][x+1]->m_IsSmall == false &&
			m_Board[y][x]->m_Type == m_Board[y-1][x+1]->m_Type)

		{	
			if(XList.size() == 0)
			{
				XList.push_back(x);
				YList.push_back(y);
			}

			XList.push_back(x+1);
			YList.push_back(y-1);
		}	
		else
		{
			if(XList.size() >= 5)
			{

				AddToSameList(YList, XList);					
			}
			YList.clear();
			XList.clear();
		}

		x++;
		y--;
	}
	
	if(XList.size() >= 5)
	{

		AddToSameList(YList, XList);					
	}
}

void		MATLogicBoard::AddToSameList(const std::vector<int>& YList, const std::vector<int>& XList)
{
	bool AlreadyExists = false;
	for(int i = 0; i < (int)XList.size(); i++)
	{
		AlreadyExists = false;
		for(int j = 0; j < (int)m_SameXs.size(); j++)
		{
			if( m_SameXs[j] == XList[i] && m_SameYs[j] == YList[i])
			{
				AlreadyExists = true;
			}			
		}

		if(!AlreadyExists)
		{
			m_SameXs.push_back(XList[i]);
			m_SameYs.push_back(YList[i]);
		}
	}
}


void		MATLogicBoard::ClearMatch()
{
	int y = 0;
	int x = 0;

	std::vector<MATGem*> List;
	
	for(int j = 0; j < (int)m_SameXs.size(); j++)
	{
		y = m_SameYs[j];
		x = m_SameXs[j];
		List.push_back(m_Board[y][x]);

		if(m_Board[y][x]->m_IsTimeBonus)
		{
			MATSFXManager::Instance().Spawn(MATSfx::SFX_BONUS_TIME, MATGame::GetBoardPos(y,x),1.0f,0,false,MATSounds::SFX_BONUS_TIME);								
		}
		
		// bombs got special treatment
		if(m_Board[y][x]->m_IsBomb)
		{
			MATSFXManager::Instance().Spawn(MATSfx::SFX_BOMBMATCH, MATGame::GetBoardPos(y,x),1.0f,0,false,MATSounds::SFX_MATCH);					
			m_Board[y][x]->m_IsFinish = true;
			m_Board[y][x] = NULL;
		}
		else if(m_Tiles[y][x] != TILE_UNMOVEABLEGEM && m_Tiles[y][x] != TILE_UNMOVEABLEGEM2)		// will only make it moveable
		{
			MATAnimationManager::Instance().AddAnimation(y, x, m_Board[y][x] , MATAnimation::ANI_TYPE_MATCHED);
			MATGemCollect::Instance().Add( MATGame::GetBoardPos(y,x) , MATGame::GetSpriteByGem(m_Board[y][x] ) , 0.35f);
			MATSFXManager::Instance().Spawn(MATSfx::SFX_MATCH, MATGame::GetBoardPos(y,x),1.0f,0,false,MATSounds::SFX_MATCH);					
			m_Board[y][x]->m_IsFinish = true;
			m_Board[y][x] = NULL;
		}	

		
		
	}
	if((int)m_SameXs.size() > 0)
	{
		ClearTilesByMatch();		
		MATScoring::Instance().AddMatched(	List,
											m_SameXs,
											m_SameYs,
											m_LastMoveToX,
											m_LastMoveToY,
											m_LastMoveX,
											m_LastMoveY
											);
	}
	
	m_SameXs.clear();
	m_SameYs.clear();

	
}

void		MATLogicBoard::ClearTilesByMatch()
{
	int Y,X;
	for(int j = 0; j < (int)m_SameXs.size(); j++)
	{	Y = m_SameYs[j];
		X = m_SameXs[j];
		
		if(m_Tiles[Y][X] > TILE_NORMAL )
		{
			if(m_Tiles[Y][X] == TILE_UNMOVEABLEGEM || m_Tiles[Y][X] == TILE_UNMOVEABLEGEM2)
				MATSFXManager::Instance().Spawn(MATSfx::SFX_TILEUNMOVEABLE_EXPLODE,MATGame::GetBoardPos(Y,X),1.0f,0,false,MATSounds::SFX_EXPLODE_TRAP);

			else if(m_Tiles[Y][X] == TILE_UNREACHABLE || m_Tiles[Y][X] == TILE_UNREACHABLE2)
				MATSFXManager::Instance().Spawn(MATSfx::SFX_TILE_EXPLODE,MATGame::GetBoardPos(Y,X),1.0f,0,false,MATSounds::SFX_EXPLODE_TILE);

			else
				MATSFXManager::Instance().Spawn(MATSfx::SFX_TILE_EXPLODE,MATGame::GetBoardPos(Y,X),1.0f,0,false,MATSounds::SFX_EXPLODE_TILE);

			if(m_Tiles[Y][X] == TILE_UNMOVEABLEGEM )
				m_Tiles[Y][X] = TILE_NORMAL;
			else if(m_Tiles[Y][X] == TILE_UNMOVEABLEGEM2)
				m_Tiles[Y][X] = TILE_HARD;
			else
				m_Tiles[Y][X] = TILE_TYPE((int)m_Tiles[Y][X] - 1); 			

		}
	}

	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{		
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Tiles[y][x] == TILE_UNREACHABLE || m_Tiles[y][x] == TILE_UNREACHABLE2)
			{
				if( IsMatchedXY(y-1,x) || IsMatchedXY(y+1,x) || IsMatchedXY(y,x-1) || IsMatchedXY(y,x+1) ||
					IsMatchedXY(y-1,x-1) || IsMatchedXY(y+1,x -1) || IsMatchedXY(y - 1,x+1) || IsMatchedXY(y + 1,x+1)

					)
				{
					if(m_Tiles[y][x] == TILE_UNREACHABLE )
						m_Tiles[y][x] = TILE_NORMAL;
					else if(m_Tiles[y][x] == TILE_UNREACHABLE2)
						m_Tiles[y][x] = TILE_HARD;
					else
						m_Tiles[y][x] = TILE_TYPE((int)m_Tiles[y][x] - 1); 	

					MATSFXManager::Instance().Spawn(MATSfx::SFX_UNREACHABLE_EXPLODE ,MATGame::GetBoardPos(y,x),1.0f,0,false,MATSounds::SFX_EXPLODE_TILE);
				}
				
			}
		}
	}
}

bool		MATLogicBoard::IsAllTileClear() const
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{		
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Tiles[y][x] == TILE_HARD || m_Tiles[y][x] == TILE_UNMOVEABLEGEM2 || m_Tiles[y][x] == TILE_UNREACHABLE2 )
				return false;
		}
	}
	return true;
}

bool		MATLogicBoard::IsEmpty() const
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if( m_Board[y][x] && m_Board[y][x]->m_Type != 0)
				return false;
		}

	}
	return true;
}


void		MATLogicBoard::OnAnimationFinish(MATAnimation::ANI_TYPE AnimationType)
{
	
	if(CheckMatch5() == false || GetGemCount() < 6 || MATGameRule::Instance().IsTutorialActive())
	{
		MATGameRule::Instance().NextTurn();
	}
			
	MATLevelManager::Instance().NextMove();
	
}

bool		MATLogicBoard::IsMatchedXY(int Y,int X)
{
	for(int j = 0; j < (int)m_SameXs.size(); j++)
	{
		if( Y == m_SameYs[j] && X == m_SameXs[j])
			return true;		
	}
	return false;
}

void		MATLogicBoard::LoadLevel(const std::string& File)
{
	ClearTiles();

	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	if (!ScriptHelper::DoFile(*pScript, File))
	{
		LuaPlus::LuaState::Destroy( pScript );
		//return;
	} 	
	
	else
	{
		
		{	//fix RAII bug
			LuaPlus::LuaObject TileTable = pScript->GetGlobal("Tiles");
			for(int i =0; i <TileTable.GetTableCount(); i++)
			{
				LuaPlus::LuaObject Obj = TileTable.GetByIndex(i+1);

				int TileType = ScriptHelper::GetTableInt(Obj,"Type"); 
				int X = ScriptHelper::GetTableInt(Obj,"X"); 
				int Y = ScriptHelper::GetTableInt(Obj,"Y"); 

				if( X < MATGameRule::Instance().GetBoardCountX() && 
					Y < MATGameRule::Instance().GetBoardCountY() )
				{
					m_Tiles[Y][X] = (TILE_TYPE)TileType;
				}

			}

		}  //fix RAII bug

		{	//fix RAII bug
			LuaPlus::LuaObject BombTable = pScript->GetGlobal("Bombs");
			if(!BombTable.IsTable())
			{}else
			{
				for(int i =0; i <BombTable.GetTableCount(); i++)
				{
					LuaPlus::LuaObject Obj = BombTable.GetByIndex(i+1);

					int BombType = ScriptHelper::GetTableInt(Obj,"Type"); 
					int X = ScriptHelper::GetTableInt(Obj,"X"); 
					int Y = ScriptHelper::GetTableInt(Obj,"Y"); 

					if( X < MATGameRule::Instance().GetBoardCountX() && 
						Y < MATGameRule::Instance().GetBoardCountY() )
					{
						MATGem* pGem = MATGameRule::Instance().GetNewGemToSpawn();
						pGem->m_IsBomb = true;
						//pGem->m_Type = BombType;
						pGem->m_IsSmall = false;
						pGem->m_BombTurnToExplode = 21;

						SetContentAt(Y,X, pGem);
					}

				}
			}

		}  //fix RAII bug

	LuaPlus::LuaState::Destroy( pScript );
	}

	
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{		
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Tiles[y][x] == TILE_UNMOVEABLEGEM || m_Tiles[y][x] == TILE_UNMOVEABLEGEM2)
			{
				if( m_Board[y][x] == NULL)
				{

					MATGem* pBC = MATGameRule::Instance().GetNewGemToSpawn();
					pBC->m_IsSmall = false;
					SetContentAt(y,x,  pBC );
				}
			}
		}
	}
	MATGameRule::Instance().NewGame();
	
	
}

void	MATLogicBoard::Save(const std::string& File)
{
	WriteLua	wl;
	if (!wl.Open(File)) return;

	wl.StartTable("Tiles");
	{
		for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
		{		
			for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
			{
				if(m_Tiles[y][x] > 0)
				{
					wl.StartTable();
					wl.WritePair("Type", m_Tiles[y][x]);
					wl.WritePair("X", x);
					wl.WritePair("Y", y);
					wl.CloseTable();
				}
			}
		}
	}
	wl.CloseTable(false);

	wl.StartTable("Bombs");
	{
		for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
		{		
			for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
			{
				if(m_Board[y][x] && m_Board[y][x]->m_IsBomb)
				{
					wl.StartTable();
					wl.WritePair("Type", m_Board[y][x]->m_Type );
					wl.WritePair("X", x);
					wl.WritePair("Y", y);
					wl.CloseTable();
				}
			}
		}
	}
	wl.CloseTable(false);
}

void	MATLogicBoard::ChangeTile(int y, int x, TILE_TYPE Type)
{
	if( x < MATGameRule::Instance().GetBoardCountX() && 
			y < MATGameRule::Instance().GetBoardCountY() )
	{
		m_Tiles[y][x] = Type;
	}
}

void	MATLogicBoard::ClearTiles()
{
	// clear all tiles first
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{		
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			m_Tiles[y][x] = TILE_NORMAL;
		}
	}
}

int		MATLogicBoard::GetGemCount() const
{
	int Count = 0;
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Board[y][x] == false)
				continue;

			if( m_Board[y][x]->m_IsSmall == false &&
				(m_Tiles[y][x] != TILE_UNMOVEABLEGEM || m_Tiles[y][x] != TILE_UNMOVEABLEGEM2)  &&
				m_Board[y][x]->m_IsMarkedClearing == false
				)
			{
				Count++;
			}
		}
	}
	return Count;
}

void	MATLogicBoard::ClearMarkedClearing()
{
	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			if(m_Board[y][x])
				m_Board[y][x]->m_IsMarkedClearing = false;
		}
	}
}

void	MATLogicBoard::SetMarkedClearing(int Y, int X)
{
	m_Board[Y][X]->m_IsMarkedClearing = true;
}
